﻿using System.Collections.Generic;

// 事件ID
public enum EventID
{
    BEGIN = 0,

    // 启动步骤
    START_GAME,         // 启动游戏
    START_LOAD,         // 启动加载模块
    START_LUA,          // 启动Lua模块

    START_FINISH,       // 启动完成

    END = 100,
}

// ----------------------------------------------------------------------------------------------
// 事件定义
// 带参数列表的事件
public class ParamsEvent : EventBase
{
    public object[] m_args;
    public ParamsEvent(EventID id, params object[] args)
        : base(id)
    {
        m_args = args;
    }
}

// 带回调的事件
public class CallbackEvent : ParamsEvent
{
    public delegate void FinishCallback();

    FinishCallback m_onFinish;
    public CallbackEvent(EventID id, FinishCallback onFinish, params object[] args)
        : base(id, args)
    {
        m_onFinish = onFinish;
    }

    public virtual void OnFinish()
    {
        if (m_onFinish != null)
        {
            m_onFinish();
        }
    }
}



// ------------------------------------------------------------------------------------------------
// 事件队列(按顺序执行事件,最终回调)
public class EventQueue
{
    public delegate void FinishCallback();

    bool m_usePost;
    FinishCallback m_onFinish;
    Queue<EventID> m_ids = new Queue<EventID>();
    public EventQueue(FinishCallback onFinish, params object[] ids)
    {
        m_onFinish = onFinish;

        EventID id = 0;
        for (int i = 0; i < ids.Length; ++i)
        {
            id = (EventID)ids[i];
            if (id != 0)
            {
                m_ids.Enqueue(id);
            }
        }
    }

    EventBase NextEvent
    {
        get
        {
            bool has = false;
            EventID id;
            do
            {
                id = m_ids.Dequeue();
                has = Framework.Instance.HasEventProc((int)id);
            } while (!has && m_ids.Count > 0);

            if (has)
            {
                return new CallbackEvent(id, OnEventFinish);
            }
            else
            {
                CheckFinish();
                return null;
            }
        }
    }

    bool CheckFinish()
    {
        if (m_ids.Count > 0)
        {
            return false;
        }

        if (m_onFinish != null)
        {
            m_onFinish();
        }

        return true;
    }

    void OnEventFinish()
    {
        if (m_usePost)
        {
            Post();
        }
        else
        {
            Send();
        }
    }

    public void Post()
    {
        m_usePost = true;
        if (!CheckFinish())
        {
            EventBase evt = NextEvent;
            if (evt != null)
            {
                evt.Post();
            }
        }
    }

    public void Send()
    {
        m_usePost = false;
        if (!CheckFinish())
        {
            EventBase evt = NextEvent;
            if (evt != null)
            {
                evt.Send();
            }
        }
    }
}